<?php
/**
 * Created by PhpStorm.
 * User: conlin
 * Date: 2019/8/23 0023
 * Time: 下午 1:42
 */
namespace app\wxsite\controller;
use think\Controller;
use think\Db;
use think\Request;
Class LoginController extends Controller{
    protected $client = 1;  //  1:客户端是微信  2：客户端是支付宝
    protected $openid = '';
    protected $uid = 0;
    protected $user;
    private $userTable = 'user'; //用户表 user
    public $className ;
    protected $debug = false;
    protected $debugList = [
        'conlin' => 141//141是uid
    ];
    //免登陆action     $authWhiteList = false  该类的方法都免登陆
    protected $authWhiteList = [];
    protected $baseAuthWhiteList = ['login', 'wxLogin','sendCode','setPassword'];
    public function _initialize(){
        parent::_initialize();
        $api_name = input('api_name','','trim');
        $token = input('token','','trim');
        $request= Request::instance();
        $this->className = lcfirst($request->controller());
        if($this->is_alinput())
        { //是支付宝
            $this->client = 2;
        }
        //白名单

        if(!in_array($api_name,$this->authWhiteList?:[])&&$this->authWhiteList!==false&&!in_array($api_name,$this->baseAuthWhiteList))
        {

            //调试模式 $debug=true，token 填入conlin  可以找到的uid，方便做调试
            if ($this->debug && array_key_exists($token,$this->debugList)) {
                $this->uid = $this->debugList[$token];
                $this->openid = Db::name(self::$userTable)->where(['id'=>$this->uid])->getField('openid');
            }
            else if(isset($token) && !empty($token))
            {
                //jwttoken
                vendor('Jwt.Jwt');
                try{
                    $log_token = $token;
                    $token = \Jwt::decode($token,'Dlc');
                }catch(\Exception $e)
                {
                    header("content-type:application/json;charset=utf-8");
                    exit(json_encode([ 'code' => 1000, 'msg' => 'token error']));
                }
                if(is_array($token)  && isset($token['uid']) && isset($token['signure']))
                {
                    if(md5($token['uid'].$token['oid']) !== $token['signure'])
                    {
                        header("content-type:application/json;charset=utf-8");
                        exit(json_encode([ 'code' => 1000, 'msg' => 'login error3']));
                    }
                    //判断token过期时间
                    if($token['exp'] < time()){
                        exit(json_encode([ 'code' => 1000, 'msg' => '登录过期,请重新登录']));
                    }
                    //判断token 的用户id 和openID是否是数据库存在
                    $get_user_data = Db::name($this->className)->where(['id'=>$token['uid'],'token'=>$log_token])->find();
                    if($get_user_data){
                        //判断是否有 状态字段
                        if (array_key_exists ( 'status' ,  $get_user_data )){
                            if ($get_user_data['status']!=1) api_return(0,'账号已被禁用，登录失败');
                        }
                        //判断token 是否是该用户数据库更新
                        if($log_token != $get_user_data['token']){
                            exit(json_encode([ 'code' => 1000, 'msg' => '登录失效，请重新登录']));
                        }
                        $this->uid = $token['uid'];   //用户ID
                        $this->openid = $token['oid'];   //openid
                        $this->user = $get_user_data;
                    }else{
                        exit(json_encode([ 'code' => 1000, 'msg' => '账号不存在']));
                    }


                }else{
                    header("content-type:application/json;charset=utf-8");
                    exit(json_encode([ 'code' => 1000, 'msg' => 'login error2']));
                }
            }else{
                header("content-type:application/json;charset=utf-8");
                exit(json_encode([ 'code' => 1000, 'msg' => 'login error1']));
            }
        }
    }
    /**
     * 登陆方法
     * @param  int      $username  | 账号 对于的字段
     * @param  string   $password | 密码对应的字段
     * @param  int      $code     | 短信验证码  对于的字段
     * @return [type] [description]
     */
    public function login($username = 'phone',$password = 'password',$code = 'code'){
        $post = input('post.','','trim');
        if(empty($post[$username])) api_return(-1,'帐号不能为空');
        if(empty($post[$password])&&empty($post[$code])) api_return(-1,'缺少参数');
        $user = Db::name($this->className)->where([$username=>$post[$username]])->find();
        if (!empty($post[$password])){
            if ($user[$password] != md5($post[$password])) api_return(0,'密码有误！');
        }
        elseif(!empty($post[$code])){
            //验证码效验
            vendor('SMS.SmsService');
            \SmsService::factory('AliSms');
            $chceck = \SmsService::verfyCode($post[$code],$post[$username]);
            if(!$chceck){
                api_return(0,'验证码错误');
            }
        }
        $token = $this->createToken($user['id'], $user['openid']);
        //token更新到数据库
        $upd_token = Db::name($this->className)->where(['id'=>$user['id']])->update(['token'=>$token]);
        if($upd_token !== false){
            api_return(1,'登录成功',['token'=>$token]);
        }else{
            api_return(-1,'登录失败');
        }
    }

    public function wxLogin(
        $fieldArr = ['nickname', 'sex', 'province', 'city', 'country', 'headimgurl', 'unionid'] //接收微信返回的用户信息字段
        , $unique = 'openid' //数据库定义微信openid的字段名
    ){
        $code = input('param.code');
        $config = config('WeChat');
        vendor('WxPayPubHelper.Lar');
        $obj = new \WeChat($config);
        if(!$obj->authorize($code)) api_return(0, $obj->errMsg);
        if(!$userInfo = $obj->getUserInfo()) api_return(0, $obj->errMsg);
        $fieldArr[] = 'openid';
        foreach ($userInfo as $key => $value) {
            if(!in_array($key, $fieldArr)) unset($userInfo[$key]);
        }
        $table = Db::name($this->className);
        $row = $table->where([$unique => $userInfo['openid']])->find();
        $userInfo['token'] = $this->createToken($row['id'], $userInfo['openid']);
        if($row){
            $table->where('id', $row['id'])->update($userInfo);
        } else {
            $userInfo['ctime'] = time();
            $row['id'] = $table->insertGetId($userInfo);
            $row += $userInfo;
        }
        api_return(1, '登录成功', $row);
    }

    protected function createToken($id, $oid){//创建登录token
        $payload = [
            'iat' => time(), //什么时候签发的
            'exp' => strtotime("+1 month"), //过期时间 0永不过期
            'oid' => $oid, //加盐
            'uid' => $id, //主体id
            'signure'=>md5($id.$oid)
        ];
        vendor('Jwt.Jwt');
        $token = \Jwt::encode($payload, 'Dlc');
        return $token;
    }

    //设置密码
    public function setPassword($password = 'password'){
        $post = input('post.');
        $this->uid = $post['uid'];
        if(empty($post[$password])) api_return(-1,'密码不能为空');
        $res = Db::name($this->className)->where(['id'=>$this->uid])->update([$password=>md5($post[$password])]);
        if ($res) api_return(1,'设置成功');
        api_return(0,'失败');
    }


    /**
     * 发送验证码
     *
     */
    public function sendCode(){
        $mobile = I('mobile');
        if (empty($mobile)) {
            $info['code'] = -1;
            $info['msg'] = '手机不能为空';
            $this->ajaxReturn($info);
        }
        if (!is_mobile($mobile)) {
            $info['code'] = -1;
            $info['msg'] = '手机格式有误';
            $this->ajaxReturn($info);
        }

        //查询上次发送的时间
        $info = M('sms_recard')->where(['mobile'=>$mobile])->order('recard_id desc')->find();
        if ($info) {
            if (time() - $info['ctime']  < 300) {

                $this->ajaxReturn(['code'=>-1,'msg'=>'短信发送太频繁']);
            }
        }

        vendor('SMS.SmsService');
        $code = mt_rand(1000, 9999);

//        \SmsService::factory('ZTSms');
//        $content =  '【眼波堂】您的验证码为' . $code . ',如非本人操作，请忽略本短信';
        //阿里云短信
        \SmsService::factory('AliSms');
        $content =  'SMS_172205186';
//        $res = \SmsService::sendMsg($mobile,$content,$code,360);
//        dump($res);die();

        //短信发送验证码
        if ($res = \SmsService::sendMsg($mobile,$content, ['code'=>$code],360)) {
            M('sms_recard')->add([
                'code'=>$code,
                'type'=>1,
                'status'=>1,
                'mobile'=>$mobile,
                'content'=>$content,
                'ctime'=>$_SERVER['REQUEST_TIME']
            ]);
            $this->ajaxReturn(['code'=>1,'msg'=>'success']);
        } else {
            M('sms_recard')->add([
                'code'=>$code,
                'type'=>1,
                'status'=>-1,
                'mobile'=>$mobile,
                'content'=>$content,
                'ctime'=>$_SERVER['REQUEST_TIME']
            ]);
            $this->ajaxReturn(['code'=>-1,'msg'=>'send error']);
        }
    }
    protected function is_weixin(){
        if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) {
            return true;
        }
        return false;
    }

    protected function is_alinput()
    {
        if (strpos($_SERVER['HTTP_USER_AGENT'], 'AlipayClient') !== false) {
            return true;
        }
        return false;
    }
}